package com.example.auth.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.exception.ExcelCommonException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.auth.consts.IndexConst;
import com.example.auth.entity.SysRole;
import com.example.auth.entity.SysUser;
import com.example.auth.entity.SysUserRole;
import com.example.auth.entity.dto.*;
import com.example.auth.entity.vo.SysUserQueryVO;
import com.example.auth.excel.SysUserExportExcel;
import com.example.auth.excel.SysUserImportExcel;
import com.example.auth.exception.LyException;
import com.example.auth.listener.SysUserListener;
import com.example.auth.mapper.ISysUserMapper;
import com.example.auth.mapper.SysRoleMapper;
import com.example.auth.service.SysUserService;
import com.example.auth.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author SIE
* @description 针对表【sys_user(用户表)】的数据库操作Service实现
* @createDate 2023-07-07 13:05:31
*/
@Service
@Slf4j
public class SysUserServiceImpl  extends ServiceImpl<SysUserMapper, SysUser>
    implements SysUserService{


    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private SysUserListener sysUserListener;

    @Override
    public void insert(SysUserCreateDTO sysUserCreateDTO) {
        if(ObjectUtils.isEmpty(sysUserCreateDTO)){
            throw new LyException("请求的对象不能为空");
        }
        String username = sysUserCreateDTO.getUsername();
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername,username);
        if(!ObjectUtils.isEmpty(sysUserMapper.selectOne(wrapper))){
            throw new LyException("该用户名已经存在了");
        }
        String password = sysUserCreateDTO.getPassword();
        sysUserCreateDTO.setPassword(passwordEncoder.encode(password));
        SysUser sysUser = ISysUserMapper.INSTANCT.sysUserCreateDTOToSysUser(sysUserCreateDTO);
        System.out.println(sysUser);
        sysUserMapper.insert(sysUser);
    }

    @Override
    public Page<SysUserQueryVO> selectUserPage(Long pageNum, Long pageSize, SysUserQueryDTO sysUserQueryDTO) {
        Page<SysUserQueryVO> sysUserPage = new Page<>(pageNum, pageSize);
        return sysUserMapper.selectUserPage(sysUserPage,sysUserQueryDTO);

    }

    @Override
    public SysUserQueryVO getUserById(Long id) {
        SysUser sysUser = sysUserMapper.selectById(id);
        return  ISysUserMapper.INSTANCT.sysUserToSysUserQueryVO(sysUser);

    }

    @Override
    public void updateUser(SysUserEditDTO sysUserEditDTO) {
        if(ObjectUtils.isEmpty(sysUserEditDTO)){
            throw new LyException("请求的对象不能为空");
        }
        SysUser sysUser = ISysUserMapper.INSTANCT.sysUserEditDTOToSysUser(sysUserEditDTO);
        sysUserMapper.updateById(sysUser);
    }

    @Transactional(rollbackFor = {Throwable.class})
    @Override
    public Map<String, Object> getRolesByUserId(Long userId) {
        //根据用户id查询有效的已分配的角色
        List<SysUserRole> sysUserRoleList = sysUserMapper.getRolesByUserId(userId);
        List<Long> userRoleIds = new ArrayList<Long>();
        sysUserRoleList.forEach(sysUserRole -> {
            userRoleIds.add(sysUserRole.getRoleId());
        });
        //返回所有的有效角色
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getStatus, IndexConst.STATUS_OPEN);
        var roles = sysRoleMapper.selectList(wrapper);
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("allRoles",roles);
        map.put("userRoleIds",userRoleIds);
        return map;
    }

    @Override
    @Transactional(rollbackFor = {Throwable.class})
    public void doAssign(AssignRoleDTO assignRoleDTO) {
        var userId = assignRoleDTO.getUserId();
        //先删除用户原有的角色
        sysUserMapper.deleteUserRoleByUserId(userId);

        var userRoleIds = assignRoleDTO.getUserRoleIds();
        if(!ObjectUtils.isEmpty(userRoleIds)){
            //批量插入
            sysUserMapper.doAssign(userId,userRoleIds);
        }

    }

    @Transactional(rollbackFor = {Throwable.class})
    @Override
    public void removeUserById(Long userId) {
        sysUserMapper.deleteById(userId);
        sysUserMapper.deleteUserRoleByUserId(userId);
    }

    @Override
    public void updateUserStatus(Long userId, Long status) {
        sysUserMapper.updateUserStatus(userId,status);
    }

    @Override
    public void exportUserInfoExcel(HttpServletResponse response) {
        List<SysUser> sysUserList = sysUserMapper.selectList(null);
        List<SysUserExportExcel> sysUserExportExcelList = ISysUserMapper.INSTANCT.sysUserToSysUserExportExcel(sysUserList);
        try {
            String fileName = URLEncoder.encode("用户信息","UTF-8");
            response.setHeader("Content-disposition","attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), SysUserExportExcel.class)
                    .sheet("用户信息表")
                    .doWrite(sysUserExportExcelList);
        } catch (Exception e) {
            throw new LyException("导出失败");
        }
    }

    @Transactional(rollbackFor = {Throwable.class})
    @Override
    public void removeBatch(List<Long> idList) {
        sysUserMapper.deleteBatchUserRoleByUserId(idList);
        sysUserMapper.deleteBatchIds(idList);
    }

    @Override
    public void importUserInfoExcel(MultipartFile file) {
        if (file.isEmpty()) {
            return;
        }
        try {
            EasyExcel.read(file.getInputStream(), SysUserImportExcel.class,sysUserListener)
                    .sheet().doRead();
        }catch (ExcelCommonException e){
            throw new LyException("上传的文件只能是 excel ");
        }catch (IOException e) {
            throw new LyException("导入失败");
        }
    }
}




